package one.stand.util;

import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Objects;

import static one.stand.util.ImageGenerateUtil.getUrlByBufferedImage;

/**
 * @author: QIK
 * @CreateDate: 2019/4/15 15:06
 */
@Slf4j
public class ImageGenerateUtil2 {
    private static String frefix = "png";
    private static String typeface = "NotoSansHans";

    /**
     * 自定义海报生成
     */
    public static InputStream cardDiy(TemplateEntity template) {
        if (OneListUtil.isEmpty(template.getEntities())) {
            log.warn("template entities is empty");
        }

        Graphics2D g2d = null;
        try {

            //初始化
            BufferedImage bimg = Objects.nonNull(template.getImage()) ? template.getImage() : getUrlByBufferedImage(template.getBackUrl());//读取图片文件，得到BufferedImage对象
            g2d = (Graphics2D) bimg.getGraphics();//得到Graphics2D 对象
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿
            int w = bimg.getWidth();
            int h = bimg.getHeight();
            log.info("img:{} {}", w, h);
            CreateContext context = new CreateContext();
            context.setImgWidth(w);
            context.setImgHeigth(h);

            //绘图
            for (Entity entity : template.getEntities()) {
                entity.draw(g2d, context);
            }

            //保存新图片
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(bimg, frefix, os);
            return new ByteArrayInputStream(os.toByteArray());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (Objects.nonNull(g2d)) {
                // 释放对象
                g2d.dispose();
            }
        }

        return null;
    }

    @Data
    public static class TemplateEntity {
        private String backUrl;
        private BufferedImage image;
        private List<Entity> entities;
    }

    @Data
    public static class CreateContext {
        private int imgWidth;
        private int imgHeigth;
    }

    public interface Entity {
        void draw(Graphics2D g2d, CreateContext context) throws Exception;
    }

    @Data
    @Builder
    public static class FontEntity implements Entity {
        private Integer xAxis;
        private Integer yAxis;
        private String name;
        private Integer style;
        private Integer size;

        private String content;
        private Color color;

        /**
         * 水平居中
         */
        private boolean wcenter;

        @Override
        public void draw(Graphics2D g2d, CreateContext context) {
            if (StringUtils.isBlank(name)) {
                name = typeface;
            }
            if (Objects.isNull(style)) {
                style = Font.PLAIN;
            }
            if (Objects.isNull(color)) {
                color = Color.BLACK;
            }
            if (Objects.isNull(size)) {
                size = 24;
            }

            g2d.setColor(color);
            Font font = new Font(name, style, size);
            g2d.setFont(font);
            if (wcenter) {
                xAxis = xPlay(g2d, font, content, context.getImgWidth());
            }
            g2d.drawString(content, xAxis, yAxis);
        }

        private int xPlay(Graphics2D g2d, Font font, String text, int w) {
            FontMetrics fm = g2d.getFontMetrics(font);
            int textWidth = fm.stringWidth(text);
            return (w - textWidth) / 2;
        }
    }

    @Data
    @Builder
    public static class ImageEntity implements Entity {
        private Integer xAxis;
        private Integer yAxis;
        private String url;
        private InputStream inputStream;
        private Image image;
        private Integer width;
        private Integer height;

        /**
         * 水平居中
         */
        private boolean wcenter;

        @Override
        public void draw(Graphics2D g2d, CreateContext context) throws Exception {
            if (Objects.isNull(this.image) && StringUtils.isNoneBlank(url)) {
                image = getUrlByBufferedImage(url);
            } else if (Objects.isNull(this.image) && Objects.nonNull(inputStream)) {
                image = ImageIO.read(inputStream);
            }
            if (wcenter) {
                xAxis = (context.getImgWidth() - width) / 2;
            }
            g2d.drawImage(image, xAxis, yAxis, width, height, null);
        }

        /**
         * 通过网络获取图片
         */
        private BufferedImage getUrlByBufferedImage(String url) throws Exception {
            URL urlObj = new URL(url);
            BufferedImage bufImg = ImageIO.read(urlObj);

//        HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
//        // 连接超时
//        conn.setDoInput(true);
//        conn.setDoOutput(true);
//        conn.setConnectTimeout(25000);
//        // 读取超时 --服务器响应比较慢,增大时间
//        conn.setReadTimeout(25000);
//        conn.setRequestMethod("GET");
//        conn.addRequestProperty("Accept-Language", "zh-cn");
//        conn.addRequestProperty("Content-type", "image/jpeg");
//        conn.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
//        conn.connect();
//        BufferedImage bufImg = ImageIO.read(conn.getInputStream());
//        conn.disconnect();
            return bufImg;
        }
    }
}
